package com.fcat.common.ftp;

import com.jcraft.jsch.*;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @BelongsProject: fcat-project
 * @BelongsPackage: com.fcat.project.main.util
 * @Author: 
 * @CreateTime: 2020-06-06 16:12
 * @Description:
 */
@Slf4j
public class Sftp {
    private String ip;
    private String port;
    private String username;
    private String password;
    private String projectPath;


    public Sftp(String ip, String port, String username, String password, String projectPath) {
        this.ip = ip;
        this.port = port;
        this.username = username;
        this.password = password;
        this.projectPath = projectPath;
    }

    private static Session session = null;
    private static Channel channel = null;


    public class SFTPConstants {
        public static final String SFTP_REQ_HOST = "host";
        public static final String SFTP_REQ_PORT = "port";
        public static final String SFTP_REQ_USERNAME = "username";
        public static final String SFTP_REQ_PASSWORD = "password";
        public static final int SFTP_DEFAULT_PORT = 22;
    }

    /**
     * 遍历项目所有模块jar包的绝对路径
     *
     * @return
     */
    static String getProjectModuleJarPaths(String moduleName) {
        String jarPath = null;
        //遍历项目的模块
        String localProjectPath = System.getProperty("user.dir");
        File projectFile = new File(localProjectPath);
        File[] files = projectFile.listFiles();
        for (File file : files) {
            if (!file.getName().contains(".") && file.isDirectory()) {
                String str = localProjectPath + "/target/" + moduleName + ".jar";
                File jarFile = new File(str);
                if (jarFile.exists()) {
                    log.info("存在 " + jarFile.getAbsolutePath());
                    jarPath = jarFile.getAbsolutePath();
                    break;
                } else {
                    log.error("不存在 " + jarFile.getAbsolutePath());
                }
            }
        }
        return jarPath;
    }

    public ChannelSftp getChannel(Map<String, String> sftpDetails, int timeout) throws JSchException {
        String ftpHost = sftpDetails.get(SFTPConstants.SFTP_REQ_HOST);
        String port = sftpDetails.get(SFTPConstants.SFTP_REQ_PORT);
        String ftpUserName = sftpDetails.get(SFTPConstants.SFTP_REQ_USERNAME);
        String ftpPassword = sftpDetails.get(SFTPConstants.SFTP_REQ_PASSWORD);

        int ftpPort = SFTPConstants.SFTP_DEFAULT_PORT;
        if (port != null && !port.equals("")) {
            ftpPort = Integer.valueOf(port);
        }

        JSch jsch = new JSch(); // 创建JSch对象
        session = jsch.getSession(ftpUserName, ftpHost, ftpPort); // 根据用户名，主机ip，端口获取一个Session对象
        log.info("Session created.");
        if (ftpPassword != null) {
            session.setPassword(ftpPassword); // 设置密码
        }
        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config); // 为Session对象设置properties
        session.setTimeout(timeout); // 设置timeout时间
        session.connect(); // 通过Session建立链接
        log.info("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<Session connected.>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");

        log.info("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<Opening Channel.>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        channel = session.openChannel("sftp"); // 打开SFTP通道
        channel.connect(); // 建立SFTP通道的连接
        log.info("Connected successfully to ftpHost = " + ftpHost + ",as ftpUserName = " + ftpUserName
                + ", returning: " + channel);
        return (ChannelSftp) channel;
    }

    public void closeChannel() throws Exception {
        if (channel != null) {
            if (channel.isClosed()) {
                channel.disconnect();
            }
        }
        if (session != null) {
            if (session.isConnected()) {
                session.disconnect();
            }
        }
    }

    //120.25.233.241",22,"root","Mictest200527");

    /**
     *
     */
    public void uploadJarFile(String moduleName) {
        try {
            log.info("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<-开始执行sftp->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
            Map<String, String> sftpDetails = new HashMap<String, String>();
            // 设置主机ip，端口，用户名，密码
            sftpDetails.put(SFTPConstants.SFTP_REQ_HOST, ip);
            sftpDetails.put(SFTPConstants.SFTP_REQ_PORT, port);
            sftpDetails.put(SFTPConstants.SFTP_REQ_USERNAME, username);
            sftpDetails.put(SFTPConstants.SFTP_REQ_PASSWORD, password);

            String jarFile = getProjectModuleJarPaths(moduleName);
            if (jarFile != null && jarFile.length() > 0) {
                log.info("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<-开始上传jar->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                ChannelSftp channelSftp = getChannel(sftpDetails, 60000);
                //s:::::E:\svn-53\project\trunk\fcat-project\project-netty\target\project-netty.jar
                //dst:::/root/project-netty.jar
                int index = jarFile.lastIndexOf('\\');
                String projectName = jarFile.substring(index + 1).replaceAll(".jar", "");
                FileInputStream inputStream = new FileInputStream(jarFile);
                String dst = projectPath + "/" + projectName + "/app/app.jar"; // 目标文件名
                if (inputStream != null) {
                    log.info("sftp 正在传输文件......:" + jarFile);
                    channelSftp.put(inputStream, dst);
                    log.info("sftp 传输文件完成:" + jarFile + " 到centos: " + dst);
                }
                channelSftp.quit();
                channelSftp.disconnect();
                log.info("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<-上传jar完成->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                ChannelShell channelShell = (ChannelShell) session.openChannel("shell");
                PipedInputStream pInputStream = new PipedInputStream();
                PipedOutputStream pOutputStream = new PipedOutputStream();
                channelShell.setInputStream(new PipedInputStream(pOutputStream));
                channelShell.setOutputStream(new PipedOutputStream(pInputStream));
                channelShell.connect();

                String shellCmd = "cd " + projectPath + "\r";

                pOutputStream.write(shellCmd.getBytes(StandardCharsets.UTF_8));


                log.info("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<-重启docker服务->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                int indexEx = jarFile.lastIndexOf('\\');
                String projectNameEx = jarFile.substring(indexEx + 1).replaceAll(".jar", "");
                shellCmd = "docker-compose restart " + projectNameEx + "\r/n";
                pOutputStream.write(shellCmd.getBytes(StandardCharsets.UTF_8));
                pOutputStream.flush();
                InputStreamReader isr = new InputStreamReader(pInputStream);
                BufferedReader responseBuffer = new BufferedReader(isr);
                String msg = null;
                while ((msg = responseBuffer.readLine()) != null) {
                    log.info("服务端执行信息:" + msg);
                    //done  代表重启完成  重启完成那么将推出
                    if (msg.contains("done")) {
                        log.info("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<-docker服务重启完成，关闭数据流->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
                        responseBuffer.close();
                        break;
                    }
                }
                pInputStream.close();
                pOutputStream.close();
                channelShell.disconnect();
                //test

                closeChannel();
                log.info("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<-sftp执行完成，数据流关闭完成->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
}